package net.mingsoft.basic.filter;

import javax.servlet.http.*;
import java.io.*;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.*;
import java.util.*;
import org.springframework.http.converter.json.*;
import com.fasterxml.jackson.databind.module.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.context.annotation.*;
import javax.servlet.*;
import org.apache.commons.lang3.*;
import org.slf4j.*;

public class XSSEscapeFilter implements Filter
{
    private static final Logger LOGGER;
    private static boolean IS_INCLUDE_RICH_TEXT;
    public List<String> includes;
    public List<String> excludes;
    public static List<String> excludesFiled;
    
    public XSSEscapeFilter() {
        this.includes = new ArrayList<String>();
        this.excludes = new ArrayList<String>();
    }
    
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain) throws IOException, ServletException {
        final HttpServletRequest req = (HttpServletRequest)request;
        final HttpServletResponse resp = (HttpServletResponse)response;
        if (this.handleExcludeURL(req, resp)) {
            filterChain.doFilter(request, response);
            return;
        }
        if (!this.handleIncludeURL(req, resp)) {
            filterChain.doFilter(request, response);
            return;
        }
        final XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest)request, XSSEscapeFilter.excludesFiled);
        filterChain.doFilter((ServletRequest)xssRequest, response);
    }
    
    private boolean handleIncludeURL(final HttpServletRequest request, final HttpServletResponse response) {
        if (this.includes == null || this.includes.isEmpty()) {
            return false;
        }
        final String url = request.getServletPath();
        final AntPathMatcher antPathMatcher = new AntPathMatcher();
        for (final String pattern : this.includes) {
            if (antPathMatcher.match(pattern, url)) {
                return true;
            }
        }
        return false;
    }
    
    private boolean handleExcludeURL(final HttpServletRequest request, final HttpServletResponse response) {
        if (this.excludes == null || this.excludes.isEmpty()) {
            return false;
        }
        String url = request.getServletPath();
        final String params = request.getQueryString();
        if (StringUtils.isNotBlank((CharSequence)params)) {
            url = url + "?" + params;
        }
        final AntPathMatcher antPathMatcher = new AntPathMatcher();
        for (final String pattern : this.excludes) {
            if (antPathMatcher.match(pattern, url)) {
                return true;
            }
        }
        return false;
    }
    
    @Bean
    @Primary
    public ObjectMapper xssObjectMapper(final Jackson2ObjectMapperBuilder builder) {
        final ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        final SimpleModule xssModule = new SimpleModule("XssStringJsonSerializer");
        xssModule.addSerializer((JsonSerializer)new XssStringJsonSerializer());
        objectMapper.registerModule((Module)xssModule);
        return objectMapper;
    }
    
    public void init(final FilterConfig filterConfig) throws ServletException {
        if (XSSEscapeFilter.LOGGER.isDebugEnabled()) {
            XSSEscapeFilter.LOGGER.debug("xss filter init");
        }
        final String isIncludeRichText = filterConfig.getInitParameter("isIncludeRichText");
        if (StringUtils.isNotBlank((CharSequence)isIncludeRichText)) {
            XSSEscapeFilter.IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
        }
        final String temp = filterConfig.getInitParameter("excludes");
        if (temp != null) {
            final String[] url = temp.split(",");
            for (int i = 0; url != null && i < url.length; ++i) {
                this.includes.add(url[i]);
            }
        }
    }
    
    public void destroy() {
    }
    
    static {
        LOGGER = LoggerFactory.getLogger((Class)XSSEscapeFilter.class);
        XSSEscapeFilter.IS_INCLUDE_RICH_TEXT = false;
        XSSEscapeFilter.excludesFiled = new ArrayList<String>();
    }
}
